#include "GameLogic.h"
#include "../config/FishGroup.h"
#include "../config/BulletConfig.h"
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
namespace fishingjoy
{
	namespace logic
	{
		CFishObject* CGameLogic::createFish()
		{
			int idx = CCRANDOM_0_1()*m_vecPercentPool.size();
			idx = m_vecPercentPool[idx];
			const std::vector<config::SFishData>& rFishs = config::CFishConfig::getFishData();
			const config::SFishData& rData = rFishs[idx];

			scene::ISceneObject* pS = m_pGameScene->createObject(rData.AniID);
			CFishObject* pObj = new CFishObject(pS,&rData,this);

			int maxw = config::CGameConfig::getExtendSize()+480;
			int maxh = config::CGameConfig::getExtendSize()+320;
			pObj->setDuration(360*CCRANDOM_0_1());
			pObj->setPosition(CCRANDOM_0_1()*maxw,CCRANDOM_0_1()*maxh);
			pObj->randomTarget();
			m_vecObjectsList.push_back(pObj);
			return pObj;
		}

		CFishObject* CGameLogic::createFish( int fid,int x,int y,int speed,int tx,int ty)
		{
			const std::vector<config::SFishData>& rFishs = config::CFishConfig::getFishData();
			const config::SFishData* pData = NULL;
			for(size_t i = 0; i < rFishs.size(); ++i){
				if(rFishs[i].FID == fid){
					pData = &rFishs[i];
				}
			}
			if(pData==NULL)
				return NULL;

			scene::ISceneObject* pS = m_pGameScene->createObject(pData->AniID);
			CFishObject* pObj = new CFishObject(pS,pData,this);

			int maxw = config::CGameConfig::getExtendSize()+480;
			int maxh = config::CGameConfig::getExtendSize()+320;
			pObj->setPosition(x,y);
			pObj->moveToAndDestroy(tx,ty);
			m_vecObjectsList.push_back(pObj);
			return pObj;
		}

		void CGameLogic::destroyFish( CFishObject* pObj )
		{
			if(pObj){
				std::vector<CFishObject*>::iterator it= m_vecObjectsList.begin();
				for(;it!=m_vecObjectsList.end();++it){
					if(*it == pObj){
						m_vecObjectsList.erase(it);
						delete (pObj);
						return;
					}
				}
			}
		}

		void CGameLogic::destroyBullet( CBulletObject* pObj )
		{
			if(pObj){
				std::vector<CBulletObject*>::iterator it= m_vecBulletsList.begin();
				for(;it!=m_vecBulletsList.end();++it){
					if(*it == pObj){
						m_vecBulletsList.erase(it);
						delete (pObj);
						return;
					}
				}
			}
		}

		bool CGameLogic::init( CCScene* pScene )
		{
			m_iLevel = 1;
			openSound(true);
			const std::vector<config::SFishData>& rFishs = config::CFishConfig::getFishData();
			for(size_t i = 0; i < rFishs.size(); ++i){
				const config::SFishData& rData = rFishs[i];
				for(int x = 0; x < rData.Percent; ++x){
					m_vecPercentPool.push_back(i);
				}
			}

			m_eGameState = EGS_BEGIN_MENU;
			if(pScene==NULL)
				return false;
			m_pGameScene = scene::createScene();
			if(m_pGameScene==NULL)
				return false;


			cocos2d::CCLayer* pSceneRoot = cocos2d::CCLayer::create();
			pScene->addChild(pSceneRoot);
			m_pGameScene->attachTo(pSceneRoot);

			const char* szBeginSceneBg = config::CGameConfig::getBeginSceneBg();
			m_pGameScene->setBackground(szBeginSceneBg);

			cocos2d::CCLayer* pUIRoot = cocos2d::CCLayer::create();
			pScene->addChild(pUIRoot);
			mUIMgr.init(this,pUIRoot);

			return true;
		}

		void CGameLogic::update( float dt )
		{
			if(m_eGameState != EGS_GAME_PLAY)
				return;
			m_fTime += dt;

			switch(m_iSubState)
			{
			case EGPS_NORMAL:
				{
					static float total = 0;
					total+=dt;
					if(total > 3){
						if((int)m_vecObjectsList.size()< config::CGameConfig::getMaxFishNum()){
							createFish();
						}
						total = 0;
					}

					const std::vector<fishingjoy::config::SFishGroupData>& rGroupData = fishingjoy::config::CFishGroup::getGroupData();
					for(size_t i = 0; i < rGroupData.size(); ++i){
						if(abs(m_fTime - rGroupData[i].BeginTime)<1){
							printf("change state to EGPS_GROUP_COME\n");
							m_iSubState = EGPS_GROUP_COME;

							int extend = config::CGameConfig::getExtendSize();

							float xs[] = {-extend,480+extend,	480+extend,-extend};
							float ys[] = {-extend,-extend,		320+extend,320+extend};

							std::vector<CFishObject*>::iterator it = m_vecObjectsList.begin();
							std::vector<CFishObject*>::iterator end = m_vecObjectsList.end();
							for(;it!=end;++it){
								int randx = CCRANDOM_0_1()*4;
								int randy = CCRANDOM_0_1()*4;
								(*it)->moveToAndStop(xs[randx],ys[randy]);
							}
							m_pGroupData = &rGroupData[i];
							m_fGroupTime = m_fTime;
							break;
						}
					}
				}
				break;
			case EGPS_GROUP_COME:
				{
					if(m_fTime > m_fGroupTime + GROUP_COME_TIME){
						printf("change state to EGPS_GROUP\n");
						m_iSubState = EGPS_GROUP;

						for(size_t i = 0; i < m_pGroupData->Fishs.size(); ++i){
							const config::SFishInGroup& rInGroup = m_pGroupData->Fishs[i];
							createFish(rInGroup.FID,rInGroup.OffsetX + m_pGroupData->X + m_pGroupData->AnchorX,
								rInGroup.OffsetY + m_pGroupData->Y + m_pGroupData->AnchorY,m_pGroupData->Speed
								,m_pGroupData->TargetX + m_pGroupData->AnchorX,
								m_pGroupData->TargetY + m_pGroupData->AnchorY);
						}
						m_fGroupTime = m_fTime;
						break;
					}
				}
				break;
			case EGPS_GROUP:
				{
					if(m_fTime >  m_fGroupTime + m_pGroupData->LastTime){
						printf("change state to EGPS_GROUP_GO\n");
						m_iSubState = EGPS_GROUP_GO;
						m_fGroupTime = m_fTime;
					}
				}
				break;
			case EGPS_GROUP_GO:
				{
					if(m_fTime > m_fGroupTime+ GROUP_GO_TIME){
						std::vector<CFishObject*>::iterator it = m_vecObjectsList.begin();
						std::vector<CFishObject*>::iterator end = m_vecObjectsList.end();
						for(;it!=end;++it){
							(*it)->randomTarget();
						}
						printf("change state to EGPS_NORMAL\n");
						m_iSubState = EGPS_NORMAL;
					}
				}
				break;
			}

			if(m_pGameScene)
				m_pGameScene->update(dt);

			std::vector<CFishObject*>::iterator it = m_vecObjectsList.begin();
			std::vector<CFishObject*>::iterator end = m_vecObjectsList.end();
			for(;it!=end;){
				if((*it)->needDestroyed()){
					scene::ISceneObject* pObj = (*it)->getSceneObj();
					m_pGameScene->destroyObject(pObj);
					it = m_vecObjectsList.erase(it); 
					end = m_vecObjectsList.end();
					continue;
				}
				(*it)->update(dt);
				++it;
			}

			std::vector<CBulletObject*>::iterator it2 = m_vecBulletsList.begin();
			std::vector<CBulletObject*>::iterator end2 = m_vecBulletsList.end();
			for(;it2!=end2;){
				if((*it2)->needDestroyed()){
					scene::ISceneObject* pObj = (*it2)->getSceneObj();
					m_pGameScene->destroyObject(pObj);
					it2 = m_vecBulletsList.erase(it2); 
					end2 = m_vecBulletsList.end();
					continue;
				}
				(*it2)->update(dt);
				++it2;
			}
		}

		void CGameLogic::onShoot(float x,float y,float dir )
		{
			int cost = config::CBulletConfig::getData(m_iLevel)->Cost;
			if(m_iTotalMark < cost){
				playEffect("NoBullet.wav",false);
				return;
			}

			const char *pEffect = NULL;
			switch(m_iLevel)
			{
			case 1:
				pEffect = "Silo1.wav";
				break;
			case 2:
				pEffect = "Silo2.wav";
				break;
			case 3:
				pEffect = "Silo3.wav";
				break;
			case 4:
				pEffect = "Silo4.wav";
				break;
			case 5:
				pEffect = "Silo5.wav";
				break;
			default:
				return;

			}
			playEffect(pEffect,false);

			addMark(-cost);

			scene::ISceneObject* pS = m_pGameScene->createObject(1005);
			CBulletObject* pObj = new CBulletObject(pS,this,m_iLevel);
			pObj->setPosition(x,y);
			pObj->setDuration(dir);
			m_vecBulletsList.push_back(pObj);
		}

		void CGameLogic::openSound( bool b )
		{
			m_SoundOpen = b;
			if(m_SoundOpen == true){
				playMusic(config::CGameConfig::getBgMusic());
			}
			else{
				SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
				SimpleAudioEngine::sharedEngine()->stopAllEffects();
			}
		}

		void CGameLogic::playMusic( const char* file,bool bLoop /*= true*/ )
		{
			if(m_SoundOpen==false)
				return;

			char buf[256];
			sprintf(buf,"audio/%s",file);

			std::string pFullName = buf; 
			pFullName = cocos2d::CCFileUtils::sharedFileUtils()->fullPathForFilename(pFullName.c_str());		

			SimpleAudioEngine::sharedEngine()->playBackgroundMusic(pFullName.c_str(),bLoop);
			//SimpleAudioEngine::sharedEngine()->playBackgroundMusic(pFullName,bLoop);
		}

		int CGameLogic::playEffect( const char* file,bool bLoop /*= false*/ )
		{
			if(m_SoundOpen==false)
				return -1;
			char buf[256];
			sprintf(buf,"audio/%s",file);

			std::string pFullName = buf; 
			pFullName = cocos2d::CCFileUtils::sharedFileUtils()->fullPathForFilename(pFullName.c_str());	
			return SimpleAudioEngine::sharedEngine()->playEffect(pFullName.c_str(),bLoop);
		}

		void CGameLogic::stopEffect( int h /*= -1*/ )
		{
			if(h==-1){
				SimpleAudioEngine::sharedEngine()->stopAllEffects();
			}
			else{
				SimpleAudioEngine::sharedEngine()->stopEffect(h);
			}
		}

	}
}